/*
 * Copyright (C), 2013-2016, 汇通达网络有限公司
 * FileName: DateUtil.java
 * Author:   杨振宁
 * Date:     2016-6-23 上午9:57:35
 * Description: //模块目的、功能描述      
 * History: //修改记录
 * <author>      <time>      <version>    <desc>
 * 修改人姓名             修改时间            版本号                  描述
 */
package com.htd.htdapmcommon.util;

import com.htd.htdapmcommon.constants.CommonConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Calendar;
import java.util.Date;


public class DateUtil {

    private static final Logger LOGGER = LoggerFactory.getLogger(DateUtil.class);

    private static final String ERROR_MSG = "日期转化异常";

    private static final long SIXTY = 60;

    private static final long THOUSAND = 1000;

    private static final long TWENTY_FOUR = 24;

	
    /**
     * 把日期转换成 yyyyMMdd格式的字符串
     * 
     * @param date
     * @return
     */
    public static String getShortStrDate(Date date) {
        DateFormat dateFormat = new SimpleDateFormat(CommonConstants.DATEFORMATE_YYYYMMDD);
        return dateFormat.format(date);
    }

    /**
     * 获取当前时间的前一天
     * 
     * @param date
     * @return
     */
    public static Date getNextDay(Date date) {  
        Calendar calendar = Calendar.getInstance();  
        calendar.setTime(date);  
        calendar.add(Calendar.DAY_OF_MONTH, -1);  
        date = calendar.getTime();  
        return date;  
    }
    
    /**
     * 把yyyyMMddHHmmss格式字符串转换成 Date
     * 
     * @param dateStr
     * @return
     */
    public static Date getSqlDateTimeByShortStr(String dateStr) {
        Date da = null;
        DateFormat dateFormat = new SimpleDateFormat(CommonConstants.DATEFORMATE_YYYYMMDDHHMMSS);
        try {
            da = dateFormat.parse(dateStr);
        } catch (Exception e) {
            LOGGER.error(ERROR_MSG, e);
        }
        return da;
    }
    
    /**
     * 把MMdd HHmm格式字符串转换成 Date
     * 
     * @param dateStr
     * @return
     */
    public static Date getSqlDateTimeByStr1(String dateStr) {
    	Date da = null;
    	DateFormat dateFormat = new SimpleDateFormat(CommonConstants.DATEFORMATE_MM_DD_HH_MM);
    	try {
    		da = dateFormat.parse(dateStr);
    	} catch (Exception e) {
    		LOGGER.error(ERROR_MSG, e);
    	}
    	return da;
    }
    
    /**
     * 获取指定日期样式yyyy一天开始时间
     * 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @param dateStr
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public static Date getIndexDateBeginTime(String dateStr){
    	//yyyy-MM-dd HH:mm:ss
    	String timestr = dateStr.trim()+" "+"00:00:00";
    	return DateUtil.getDateOfTimeStr(timestr,CommonConstants.DATEFORMATE_YYYY_MM_DD_HHMMSS);
    }
    
    /**
     * 
     * 功能描述: 获取指定日期样式yyyy一天开始时间<br>
     * 〈功能详细描述〉
     *
     * @param dateStr
     * @param format
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public static Date getIndexDateBeginTime(String dateStr,String format){
    	String timestr = dateStr.trim()+" "+"00:00:00";
    	return DateUtil.getDateOfTimeStr(timestr,format);
    }
    
    /**
     * 获取指定日期样式一天最大时间
     * 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @param dateStr
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public static Date getIndexDateEndTime(String dateStr){
    	String timestr = dateStr.trim()+" "+"23:59:59";
    	return DateUtil.getDateOfTimeStr(timestr,CommonConstants.DATEFORMATE_YYYY_MM_DD_HHMMSS);
    }
    
    /**
     * 获取指定日期样式一天最大时间
     * 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @param dateStr
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public static Date getIndexDateAndTypeEndTime(String dateStr){
    	String timestr = dateStr+"235959";
    	return DateUtil.getDateOfTimeStr(timestr,CommonConstants.DATEFORMATE_YYYYMMDDHHMMSS);
    }

    public static Date getIndexDateAndTypeEndTimeForMin(String dateStr){
        String timestr = dateStr+"000000";
        return DateUtil.getDateOfTimeStr(timestr,CommonConstants.DATEFORMATE_YYYYMMDDHHMMSS);
    }
    
    /**
     * 
     * 功能描述: 获取指定日期最大日期<br>
     * 〈功能详细描述〉
     *
     * @param date
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public static Date getDateMaxTime(Date date){
    	String timestr = DateUtil.formatDate(date, CommonConstants.DATEFORMATE_YYYYMMDD)+"235959";
    	return DateUtil.getDateOfTimeStr(timestr,CommonConstants.DATEFORMATE_YYYYMMDDHHMMSS);
    }
    
    /**
     * 获取指定日期格式一天最小时间
     * 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @param dateStr
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public static Date getIndexDateMinTime(String dateStr){
    	String timestr = dateStr+"000000";
    	return DateUtil.getDateOfTimeStr(timestr,CommonConstants.DATEFORMATE_YYYYMMDDHHMMSS);
    }
    
    public static Date getIndexDateMinTime(Date date){
    	String timestr = DateUtil.formatDate(date, CommonConstants.DATEFORMATE_YYYYMMDD)+"000000";
    	return DateUtil.getDateOfTimeStr(timestr,CommonConstants.DATEFORMATE_YYYYMMDDHHMMSS);
    }
    
    public static Date formatDateForYYYYMMDD(Date date) {
    	String strYYYYMMDD = getStrDate(date);
    	return DateUtil.getDateOfTimeStr(strYYYYMMDD,CommonConstants.DATEFORMATE_YYYY_MM_DD);
    }

    /**
     * 
     * 功能描述:根据指定格式，格式化日期 <br>
     * 〈功能详细描述〉
     * 
     * @param date
     * @param format
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public static String formatDate(Date date, String format) {
        SimpleDateFormat dateformat = new SimpleDateFormat(format);
        if (null == date) {
            return null;
        }
        return dateformat.format(date);
    }
    
    /**
     * 获取yyyyMMddHHmmss当前时间
     * 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public static String getYYYYMMDDHHMMSSNowTime(){
    	return DateUtil.formatDate(new Date(), CommonConstants.DATEFORMATE_YYYYMMDDHHMMSS);
    }

    /**
     * 
     * 功能描述: 格式成带时间的日期，格式：yyyy-MM-dd HH:mm:ss<br>
     * 〈功能详细描述〉
     * 
     * @param date
     * @return
     * @author GONGMING
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public static String formatDateWithTime(Date date) {
        return formatDate(date, CommonConstants.DATEFORMATE_YYYY_MM_DD_HHMMSS);
    }

    /**
     * 把yyyy-MM-dd HH:mm:ss.S格式的字符串转换成Date
     * 
     * @param timeStr
     * @return Timestamp
     */
    public static Date getDateOfTimeStr(String timeStr) {
        DateFormat df = new SimpleDateFormat(CommonConstants.DATEFORMATE_YYYY_MM_DD_HHMMSS);
        Date da = null;
        try {
            da = df.parse(timeStr);
        } catch (Exception e) {
            LOGGER.error(ERROR_MSG, e);
        }
        return da;
    }

    public static Date getDateOfTimeStr(String timeStr, String formateDateStr) {
        DateFormat df = new SimpleDateFormat(formateDateStr);
        Date da = null;
        try {
            da = df.parse(timeStr);
        } catch (Exception e) {
            LOGGER.error(ERROR_MSG, e);
            da = new Date();
        }
        return da;
    }

    /**
     * 把日期转换成 yyyy-MM-dd格式的字符串
     * 
     * @param date
     * @return
     */
    public static String getStrDate(Date date) {
        DateFormat dateFormat = new SimpleDateFormat(CommonConstants.DATEFORMATE_YYYY_MM_DD);
        return dateFormat.format(date);
    }
    
    /**
     * 将yyyy-mm-dd格式化成yyyymmdd
     * 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @param str
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public static String getYYYYMMDDStr(String str){
    	DateFormat df = new SimpleDateFormat(CommonConstants.DATEFORMATE_YYYY_MM_DD);
		Date d;
		try {
			d = df.parse( str);
			DateFormat dateFormat = new SimpleDateFormat(CommonConstants.DATEFORMATE_YYYYMMDD);
			return dateFormat.format(d);
		} catch (ParseException e) {
			LOGGER.error(ERROR_MSG, e);
			return "";
		}
    }

    /**
     * 把yyyy-MM-dd HH:mm:ss格式字符串转换成Date
     * 
     * @param dateStr
     * @return
     */
    public static Date getSqlDateTimeByStr(String dateStr) {
        Date da = null;
        DateFormat dateFormat = new SimpleDateFormat(CommonConstants.DATEFORMATE_YYYY_MM_DD_HHMMSS);
        try {
            da = dateFormat.parse(dateStr);
        } catch (Exception e) {
            LOGGER.error(ERROR_MSG, e);
        }
        
        return da;
    }
    
    /**
     * 把yyyy-MM-dd格式字符串转换成Date
     * 
     * @param dateStr
     * @return
     */
    public static Date getSqlDateTimeByStr2(String dateStr) {
    	Date da = null;
    	DateFormat dateFormat = new SimpleDateFormat(CommonConstants.DATEFORMATE_YYYY_MM_DD);
    	try {
    		da = dateFormat.parse(dateStr);
    	} catch (Exception e) {
    		LOGGER.error(ERROR_MSG, e);
    	}
    	
    	return da;
    }

    public static Date getMonthFirstDay() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
        SimpleDateFormat simpleFormate = new SimpleDateFormat("yyyy-MM-dd");
        return getDateOfStr(simpleFormate.format(calendar.getTime()));
    }

    public static Date getMonthLastDay() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        SimpleDateFormat simpleFormate = new SimpleDateFormat(CommonConstants.DATEFORMATE_YYYY_MM_DD_HHMMSS);
        return getDateOfStr(simpleFormate.format(calendar.getTime()));
    }

    /**
     * 获取距离今天 delay 天的日期 yyyy-MM-dd
     * 
     * @param delay
     * @return
     */
    public static String getDateStringDelay(int delay) {
        return formateDateStr(DateUtil.addDate(new Date(), delay));
    }

    /**
     * 日期相加
     * 
     * @param date 日期
     * @param day 天数
     * @return 返回相加后的日期
     */
    public static Date addDate(Date date, int day) {
        Calendar c = Calendar.getInstance();
        c.setTimeInMillis(getMillis(date) + ((long) day) * TWENTY_FOUR * SIXTY * SIXTY * THOUSAND);
        return c.getTime();
    }

    /**
     * 返回指定天数的毫秒
     * 
     * @param day int类型的天数
     * */
    public static long getMilliSeconds(int day) {
        return (long) day * TWENTY_FOUR * SIXTY * SIXTY * THOUSAND;
    }

    /**
     * 返回毫秒
     * 
     * @param date 日期
     * @return 返回毫秒
     */
    public static long getMillis(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.getTimeInMillis();
    }

    /**
     * 日期格式 yyyy-MM-dd
     * 
     * @param date
     * @return
     */
    public static String formateDateStr(Date date) {
        DateFormat dateFormat = new SimpleDateFormat(CommonConstants.DATEFORMATE_YYYY_MM_DD);
        return formateDate(date, dateFormat);
    }

    /**
     * 格式化日期格式返回字符串
     * 
     * @param date
     * @param dateFormat
     * @return
     */
    public static String formateDate(Date date, DateFormat dateFormat) {
        return dateFormat.format(date);
    }

    /**
     * 日期格式 yyyy-MM-dd HH:mm:ss
     * 
     * @param date
     * @return
     */
    public static String formateDateString(Date date) {
        if (null == date) {
            return "";
        }
        DateFormat dateFormat = new SimpleDateFormat(CommonConstants.DATEFORMATE_YYYY_MM_DD);
        return formateDate(date, dateFormat);

    }

    /**
     * 把yyyy-MM-dd格式的字符串转换成Date
     * 
     * @param dateStr
     * @return
     */
    public static Date getDateOfStr(String dateStr) {
        DateFormat df = new SimpleDateFormat(CommonConstants.DATEFORMATE_YYYY_MM_DD);
        Date da = null;
        try {
            da = df.parse(dateStr);
        } catch (Exception e) {
            LOGGER.error(ERROR_MSG, e);
        }
        return da;

    }

    /**
     * 
     * 把日期转换成 yyyyMMddHHmmss格式的字符串
     * 
     * @param date
     * @return
     */
    public static String getShortStrDateTime(Date date) {
        DateFormat dateFormat = new SimpleDateFormat(CommonConstants.DATEFORMATE_YYYYMMDDHHMMSS);
        return dateFormat.format(date);
    }

    public static String getShortStrByyyyyMMddHH(Date date) {
        DateFormat dateFormat = new SimpleDateFormat(CommonConstants.DATEFORMATE_YYYYMMDDHH);
        return dateFormat.format(date);
    }
    
    public static String formatDateToStr(Date date,String format) {
        DateFormat dateFormat = new SimpleDateFormat(format);
        return dateFormat.format(date);
    }
    

    /**
     * get current date
     * 
     * @return Date
     */
    public static Date getCurDate() {
        return getDate(getCurTime());
    }

    /**
     * 根据Timestamp获得日期
     * 
     * @param time
     * @return
     */
    public static Date getDate(Timestamp time) {
        return (new Date(time.getTime()));
    }

    /**
     * get current time
     * 
     * @return Timestamp
     */
    public static Timestamp getCurTime() {
        return new Timestamp(Calendar.getInstance().getTime().getTime());
    }

    public static String getTime() {
        Timestamp time = new Timestamp(Calendar.getInstance().getTime().getTime());
        return time.toString();
    }

    /**
     * 日期相加
     * 
     * @param date 日期
     * @param day 天数
     * @return 返回相加后的日期
     */
    public static Date minusDate(Date date, int day) {
        Calendar c = Calendar.getInstance();
        c.setTimeInMillis(getMillis(date) - ((long) day) * TWENTY_FOUR * SIXTY * SIXTY * THOUSAND);
        return c.getTime();
    }

    /**
     * 日期相加
     * 
     * @param date 日期
     * @param day 天数
     * @return 返回相加后的日期
     */
    public static Date addDate(Date date, double day) {
        Calendar c = Calendar.getInstance();
        c.setTimeInMillis((long) (getMillis(date) + day * TWENTY_FOUR * SIXTY * SIXTY * THOUSAND));
        return c.getTime();
    }

    /**
     * 分钟相加
     * 
     * @param date
     * @param minite
     * @return
     */
    public static Date addMinute(Date date, double minute) {
        Calendar c = Calendar.getInstance();
        c.setTimeInMillis((long) (getMillis(date) + minute * SIXTY * THOUSAND));
        return c.getTime();
    }

    /**
     * 功能描述: <br>
     * 某日期增加n小时
     * 
     * @param date
     * @param hours
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public static Date addHours(Date date, Integer hours) {
        Calendar c = Calendar.getInstance();
        c.setTimeInMillis((getMillis(date) + (long) hours * SIXTY * SIXTY * THOUSAND));
        return c.getTime();
    }

    /**
     * 功能描述: <br>
     * 某日期减少n小时
     * 
     * @param date
     * @param hours
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public static Date subHours(Date date, Integer hours) {
        Calendar c = Calendar.getInstance();
        c.setTimeInMillis((getMillis(date) - (long) hours * SIXTY * SIXTY * THOUSAND));
        return c.getTime();
    }

    /**
     * 功能描述: <br>
     * 某日期加n秒
     * 
     * @param date
     * @param hours
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public static Date addSeconds(Date date, Integer seconds) {
        Calendar c = Calendar.getInstance();
        c.setTimeInMillis((getMillis(date) + seconds * THOUSAND));
        return c.getTime();
    }
    
    /**
     * 
     * 功能描述: 月份相加<br>
     * 〈功能详细描述〉
     *
     * @param date
     * @param month
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public static Date addMonth(Date date, int month) {
    	Calendar c = Calendar.getInstance();
		c.add(Calendar.MONTH, month);
		return new Date(c.getTimeInMillis());
    }

    public static int diffMonth(Date nowTime, Date exTime) {
        Calendar bef = Calendar.getInstance();
        Calendar aft = Calendar.getInstance();
        bef.setTime(exTime);
        aft.setTime(nowTime);
        int result = aft.get(Calendar.MONTH) - bef.get(Calendar.MONTH);
        int month = (aft.get(Calendar.YEAR) - bef.get(Calendar.YEAR)) * 12;
        return Math.abs(month + result);
    }

    /**
     * 日期相减
     * 
     * @param date 日期
     * @param date1 日期
     * @return 返回相减后的日期
     */
    public static int diffDate(Date date, Date date1) {
        return (int) ((getMillis(date) - getMillis(date1)) / (TWENTY_FOUR * SIXTY * SIXTY * THOUSAND));
    }

    public static int diffDateToHour(Date date, Date date1) {
        return (int) ((getMillis(date) - getMillis(date1)) / (THOUSAND * SIXTY * SIXTY));
    }
    
    public static int diffDateToMIn(Date date, Date date1) {
    	long seconds = date.getTime() - date1.getTime();
    	return(int)(seconds/SIXTY);
    }

    /**
     * 功能描述: <br>
     * 两个日期间隔多少秒
     * 
     * @param firstDate
     * @param secondDate
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public static int diffSeconds(Date firstDate, Date secondDate) {
        return (int) ((getMillis(firstDate) - getMillis(secondDate)) / THOUSAND);
    }

    /**
     * 把yyyyMMdd格式字符串转换成 Date
     * 
     * @param dateStr
     * @return
     */
    public static Date getUtilDateByShortStr(String datestr) {
        DateFormat dateFormat = new SimpleDateFormat(CommonConstants.DATEFORMATE_YYYYMMDD);
        try {
            return dateFormat.parse(datestr);
        } catch (ParseException e) {
            LOGGER.error(ERROR_MSG, e);
        }
        return null;
    }

    public static String formatDateToStr(Date date) {
        DateFormat dateFormat = new SimpleDateFormat(CommonConstants.DATEFORMATE_YYYY_MM_DD_HHMMSS);
        return dateFormat.format(date);
    }

    public static Date getForwardTime(Date currentDate, Long forwardValue) {
        Long currentValue = Long.valueOf(currentDate.getTime());
        Long startValue = Long.valueOf(currentValue.longValue() - forwardValue.longValue());
        Date forwardDate = new Date(startValue.longValue());
        return forwardDate;
    }

    /**
     * 
     * 功能描述: <br>
     * 根据开始时间和结束时间参数判断当前时间是否在该时间范围内
     * 
     * @param startTime
     * @param endTime
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    public static boolean inActiveTime(String startTime, String endTime) {
        Date startDate = DateUtil.getSqlDateTimeByStr1(startTime);
        Date deadDate = DateUtil.getSqlDateTimeByStr1(endTime);
        return betweenDates(startDate, deadDate);
    }

    public static boolean betweenDates(Date startDate, Date deadDate) {
        Date currDate = new Date();
        if (deadDate == null) {
            return currDate.after(startDate);
        }
        return currDate.after(startDate) && currDate.before(deadDate);
    }

    /**
     * 把yyyyMMdd格式的字符串转换成Date
     * 
     * @param dateStr
     * @return
     */
    public static Date getDateOfShortStr(String dateStr) {
        Date da = null;
        DateFormat dateFormat = new SimpleDateFormat(CommonConstants.DATEFORMATE_YYYYMMDD);
        try {
            da = new Date(dateFormat.parse(dateStr).getTime());
        } catch (Exception e) {
            LOGGER.error(ERROR_MSG, e);
        }
        return da;
    }

    public static Date parseDate(String datestr, String dateFormate) {
        SimpleDateFormat df = new SimpleDateFormat(dateFormate);
        try {
            return df.parse(datestr);
        } catch (Exception e) {
            LOGGER.error(ERROR_MSG, e);
        }
        return null;
    }

    public static String timeStampToString(Timestamp timestamp) {
        if (null == timestamp) {
            return "";
        }
        SimpleDateFormat df = new SimpleDateFormat(CommonConstants.DATEFORMATE_YYYY_MM_DD_HHMMSS);
        try {
            return df.format(timestamp);
        } catch (Exception e) {
            LOGGER.error(ERROR_MSG, e);
        }
        return null;
    }
    
    
    public static String getTime4ES(){
//    	SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
//		Date date = new Date();
//		String str = format.format(date);
    	String str="";
    	OffsetDateTime time = ZonedDateTime.now(ZoneId.systemDefault()).toOffsetDateTime();
    	if(time!=null){
    		 str =time.toString();
    	}
		return str;
	}

}
